package cn.memorynine.consumer.model;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;

@Slf4j
public class TokenRequestWrapper extends HttpServletRequestWrapper {
    /**
     * 所有参数的Map集合
     */
    private Map<String, String[]> parameterMap;

    /**
     * token数据：字符串
     */
    private String tokenData;

    public TokenRequestWrapper( HttpServletRequest request ) {
        super(request);
        parameterMap = request.getParameterMap();
    }


    /**
     * 获取所有参数名
     */
    @Override
    public Enumeration<String> getParameterNames() {
        Vector<String> vector = new Vector<String>(parameterMap.keySet());
        return vector.elements();
    }

    /**
     * 获取指定参数名的值，如果有重复的参数名，则返回第一个的值 接收一般变量 ，如text类型
     */
    @Override
    public String getParameter( String name ) {
        String[] results = parameterMap.get(name);
        if (results != null && results.length > 0) {
            return results[0];
        }
        return null;
    }

    /**
     * 获取指定参数名的所有值的数组，如：checkbox的所有数据
     * 接收数组变量 ，如checkobx类型
     */
    @Override
    public String[] getParameterValues( String name ) {
        return this.parameterMap.get(name);
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return parameterMap;
    }

    /**
     * 重写getInputStream方法
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        //非json类型，直接返回
        if (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {
            return super.getInputStream();
        }
        //从输入流中取出body串, 如果为空，直接返回
        String body = IoUtil.read(super.getInputStream(), "utf-8");
        if (StrUtil.isEmpty(body)) {
            return super.getInputStream();
        }

        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONObject tokenJsonObject = JSONObject.parseObject(tokenData);
        tokenJsonObject.keySet().forEach(key -> {
            jsonObject.put(key, tokenJsonObject.get(key));
        });
        //log.info("token参数：" + JSON.toJSONString(jsonObject));
        //重新构造一个输入流对象
        byte[] bytes = JSON.toJSONString(jsonObject).getBytes("utf-8");
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        return new MyServletInputStream(byteArrayInputStream);
    }


    public void setTokenData( String tokenData ) {
        this.tokenData = tokenData;
    }

    public void setParameterMap( Map<String, String[]> parameterMap ) {
        this.parameterMap = parameterMap;
    }

    class MyServletInputStream extends ServletInputStream {

        private ByteArrayInputStream bis;

        public MyServletInputStream( ByteArrayInputStream bis ) {
            this.bis = bis;
        }

        @Override
        public boolean isFinished() {
            return true;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener( ReadListener listener ) {

        }

        @Override
        public int read() throws IOException {
            return bis.read();
        }
    }
}